#include "StdAfx.h"
#include "Nadajnik.h"

using namespace std;


Nadajnik::Nadajnik(void)
{
	port = new serialport("COM1");
	FillMemory(&dataToSend, sizeof(packet), 0);

	useCRC = FALSE;
	packetNumber = 1;

	crc = 0;
}

Nadajnik::Nadajnik(string _port)
{
	port = new serialport(_port);
	FillMemory(&dataToSend, sizeof(packet), 0);

	useCRC = FALSE;
	packetNumber = 1;

	crc = 0;
}


Nadajnik::~Nadajnik(void)
{
	delete port;
}

BOOL Nadajnik::sendFile(string fileName)
{
	BYTE failedRetry = 0;
	packetNumber = 1;
	WORD finalPacketSize;

	FillMemory(&dataToSend, sizeof(packet), 0);

	//Otwarcie pliku przeznaczonego do transmisji
	hFile = OpenFile(fileName.c_str(), &openFileStruct, OF_READ);
	if(hFile == HFILE_ERROR)
	{
		cout << "Blad otwarcia pliku. " << GetLastError() << endl;
		return FALSE;
	}
	
	//Odczytanie pierwszego znaku z bufora
	for (int i = 0; i <= 6; i++)
	{
		cout << "Inicjalizacja polaczenia." << endl;
		port->readABuffer(&initSign, sizeof(initSign));

		if(initSign == c)
		{
			useCRC = TRUE;
			finalPacketSize = sizeof(dataToSend);
			break;
		}
		else if (initSign == nak)
		{
			useCRC = FALSE;
			finalPacketSize = sizeof(dataToSend) - 1;
			break;
		}
		else
		{
			cout << "Nie udalo sie nawiazac polaczenia" << endl;
		}
	}	

	cout << "Pobieranie pliku..." << endl;

	BOOL eof = FALSE;

	while(true)
	{
		eof = makePacket(hFile);
		if(eof == TRUE)
		{
			break;
		}

		port->writeABuffer(&dataToSend, finalPacketSize);

		port->readABuffer(&initSign, 1);

		switch(initSign)
		{
		case ack:
			{
				failedRetry = 0;
				break;
			}
		case nak:
			{
				do
				{
					cout << "Powtarzam transmisje pakietu nr " << packetNumber << endl;
					port->writeABuffer(&dataToSend, finalPacketSize);

					port->readABuffer(&initSign, 1);

					failedRetry++;

				}
				while(initSign != ack && failedRetry <= 10);
				break;
			}
		case can:
			{
				return FALSE;
				break;
			}
		default:
			{
				do
				{
					cout << "Powtarzam transmisje pakietu nr " << (int)packetNumber << endl;
					port->writeABuffer(&dataToSend, finalPacketSize);

					port->readABuffer(&initSign, 1);

					failedRetry++;

				}
				while(initSign != ack && failedRetry <= 10);
			}
		}
	}

	if(failedRetry >= 10)
	{
		cout << "Zbyt duza liczba powtorzen transmisji" << endl;
		initSign = can;
		port->writeABuffer(&initSign, 1);
		return FALSE;
	}


	do
	{
		initSign = eot;
		port->writeABuffer(&initSign, 1);
		port->readABuffer(&initSign, 1);
	}
	while(initSign != ack);
	
	return TRUE;
}

bool Nadajnik::makePacket(HFILE _hFile)
{
	DWORD counter;

	dataToSend.startOfHeader = soh;

	if(packetNumber > 255)
	{
		packetNumber = 1;
	}
	

	dataToSend.packetNum = packetNumber;
	dataToSend.packetNumCompl = 255 - packetNumber;
	packetNumber++;
	

	BOOL readResult = ReadFile((HANDLE)hFile, &dataToSend.fileData, 128, &counter , NULL);

	if(counter < 128)
	{
		for(int i = counter; i < 128; i++)
		{
			dataToSend.fileData[i] = 0x1A;
		}
	}

	if(useCRC)
	{
		WORD tmp = CRC();
		dataToSend.checkSum1 = tmp >> 8;
		dataToSend.checkSum2 = tmp;
	}
	else
	{
		dataToSend.checkSum1 = checkSum();
	}

	if(readResult & counter == 0)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}


}

WORD Nadajnik::CRC()
{
	crc	= 0x0000;
	for (int i = 0; i < sizeof(dataToSend.fileData); i++ )
	{
		crc = crc ^ (int)dataToSend.fileData[i] << 8;
		for (int j = 0; j < 8; ++j)
		{
			if (crc & 0x8000)
			{
				crc = crc << 1 ^ 0x1021;
			}
			else
			{
				crc = crc << 1;
			}
		}
	}
	return (crc	& 0xFFFF);
}

BYTE Nadajnik::checkSum()
{
	checksum = 0x0000;

	for(int i = 0; i < sizeof(dataToSend.fileData); i++)
	{
		checksum += (BYTE)dataToSend.fileData[i];
	}

	return checksum;

}